#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009, umat
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this 
# list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice, 
# this list of conditions and the following disclaimer in the documentation 
# and/or other materials provided with the distribution.
# - The names of the contributors may not be used to endorse or promote products 
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import urllib, re, sys
from sgmllib import SGMLParser
from string import *
import htmlentitydefs, re
import wikipedia

from lybo import *

############################################
############################################

class AddAlbumToLyrics(LyricWikiUploader):

	def assign_album_to_songs(self, artist):
		"""
		Add the album to the song page by parsing the artists page
		"""
		songs = self.get_lyrics_by_album(artist)
		for album in songs:
			if album == "Other Songs": continue # don't add other songs
			print mangenta("=== ")+ bold(mangenta(album))+ mangenta(" ===")
			for song in songs[album]:
				self.update_song(artist, album, song)

	def update_song(self, artist, album, song):
		site = wikipedia.getSite()
		page = wikipedia.Page(site, song)
		try:
			lyrics = page.get(get_redirect = True)
			r = re.search("(?si)#REDIRECT\s*\[\[(.*)\]\]", lyrics)
			if r: # Follow redirects
				redirected_song = r.group(1)
				print "Redirect to %s ..." % bold(redirected_song)
				self.update_song(redirected_song, album)
				return
				
			newlyrics = self.add_album_to_lyrics(artist, album, lyrics)
			if newlyrics == lyrics: 
				print green("Nothing changed for %s" % bold(song))
				return # nothing changed
			
			comment = "Added album %s to Song template" % album
			print green("Updating %s" % bold(song))
			if self.dry:
				print comment
				print newlyrics
			else:
				page.put(newlyrics, comment=comment)

		except Exception, ex:
			print red("Failed to get song %s" % bold(song))


	def add_album_to_lyrics(self, artist, album, lyrics):
		albumlist = re.findall("(?si){{Song\|(.*?)\|(.*?)\|(.*?)}}", lyrics)
		for songalbum in albumlist: # Check if album already is assigned
			if songalbum[0] == album:
				return lyrics

		for songalbum in albumlist: # Check for empty song template
			if songalbum[0] == "":
				lyrics = re.sub("(?si){{Song\|\|(.*?\|.*?}})", "{{Song|"+album+"|\\1", lyrics)
				return lyrics
		
		# If either there is no Song template or the album is not listed yet, add a new song template to the beginning
		lyrics = "{{Song|%s|%s|star=Green}}\n%s" % (album, artist, lyrics)
		return lyrics



	def usage(self):
		progname = os.path.basename(sys.argv[0])
		print "Usage: %s [OPTION] [Artist]" % bold(progname)
		print "\Assign album to tracks linked from an artist page on %s." % bold(blue("http://lyricswiki.org"))
		print
		print "\n  %s, %-20s  dry run" % ( bold("-d"), bold("--dry") )
		print 

	def parse_arguments_and_upload(self):
		try:
		    opts, args = getopt.getopt(sys.argv[1:], "hf:dl:", ["help", "force-artist=", "dry", "language"])
		except getopt.GetoptError, err:
		    print "Error: %s" % red(str(err))
		    self.usage()
		    return 2
		self.dry = False
		forceArtist = None
		self.language = ""
		for o, a in opts:
		    if o == "-d":
			self.dry = True
		    elif o in ("-h", "--help"):
			usage()
			return 0
		    else:
			assert False, "unhandled option"

		if len(args) != 1: 
		    self.usage()
		    return 2

		artist = args[0]
		
		self.assign_album_to_songs(artist)


if __name__ == "__main__":
	ul = AddAlbumToLyrics()
	ul.parse_arguments_and_upload()

